package com.chiaching.chaoxingsecondkill.hander;

import cn.hutool.core.date.DateUtil;
import com.chiaching.chaoxingsecondkill.config.UserInfoConfig;
import com.chiaching.chaoxingsecondkill.domain.UserInfo;
import com.chiaching.chaoxingsecondkill.mapper.SubmitSeatSuccessInfoMapper;
import com.chiaching.chaoxingsecondkill.service.IMailService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author jiajing.he
 * @date 2021/3/17 21:59
 * <p>
 * <p>
 * index：http://office.chaoxing.com/front/third/apps/seat/index?appId=1000&fidEnc=cc061368ad68d8d1&uid=83751214&mappId=4950307&code=A9AOHmlv&state=33045
 */
@Component
@Slf4j
public class SecondKillHandler {

    public static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3, 30, 30, TimeUnit.MINUTES, new ArrayBlockingQueue<>(4000));

    public static ScheduledThreadPoolExecutor poolExecutor = new ScheduledThreadPoolExecutor(3);

    public static AtomicBoolean START = new AtomicBoolean(true);

    public static UserInfoConfig USER_CONFIG;

    @Resource
    private SubmitSeatSuccessInfoMapper iSubmitSeatSuccessInfoService;

    @Resource
    IMailService iMailService;

    public static List<String> TIME_INTERVAL_ONE= Arrays.asList("07:30-12:00","13:30-18:00","19:00-22:00");

    public static List<String> TIME_INTERVAL_TWO= Arrays.asList("07:30-8:30","08:30-9:30","9:30-10:30","10:30-11:30"
            ,"11:30-12:30","14:00-15:00","15:00-16:00","16:00-17:00","17:00-18:00"
            ,"19:30-20:30","20:30-21:30","21:30-22:00");

    @Resource
    public void setUserConfig(UserInfoConfig userConfig) {
        USER_CONFIG = userConfig;
    }

    public void startTaskSubmit(boolean isAdmin,List<String> timeInterval, Integer taskTime) {
        try {
            if (START.get()) {
                AtomicInteger atomicInteger = new AtomicInteger(0);
                poolExecutor.scheduleAtFixedRate(() -> {
                    log.info("当前轮次: " + atomicInteger.addAndGet(1));
                    main(taskTime,timeInterval, isAdmin);
                }, 0, 30, TimeUnit.SECONDS);
            } else {
                throw new Exception("程序运行中!");
            }
        } catch (Exception e) {
            log.info("程序异常 " + e.getMessage());
        }
    }


    /**
     * @param timeInterval 时间段
     * @param taskTime     任务执行时间 秒
     */
    public void main(Integer taskTime,List<String> timeInterval, boolean isAdmin) {
        START.set(false);
        taskTime= Objects.isNull(taskTime)?3:taskTime;
        Calendar startTime = Calendar.getInstance();
        startTime.set(Calendar.HOUR_OF_DAY, 19);
        startTime.set(Calendar.MINUTE, 58);
        startTime.set(Calendar.SECOND, 40);
        Calendar endTime = Calendar.getInstance();
        endTime.set(Calendar.HOUR_OF_DAY, 20);
        endTime.set(Calendar.MINUTE, 2);
        endTime.set(Calendar.SECOND, 0);
        Date date = new Date();
        if (startTime.getTime().compareTo(date) != 1 && endTime.getTime().compareTo(date) == 1) {
            if (!isAdmin) {
                log.info("此次执行时间: " + DateUtil.format(date, "yyyy-MM-dd HH:mm:ss") + " 高于预期不允许执行!");
                return;
            }
        }
        if (isAdmin || endTime.getTime().compareTo(date) != 1) {
            SubmitSeatFuture.OFFSET_TIME.set(1);
        } else {
            SubmitSeatFuture.OFFSET_TIME.set(0);
        }
        log.info("当前时间: " + DateUtil.formatDateTime(date) + " 时间偏移量: " + SubmitSeatFuture.OFFSET_TIME.get());
        long currentTime = System.currentTimeMillis() / 1000;
        while ((System.currentTimeMillis() / 1000) - currentTime <= taskTime) {
            try {
                ArrayList<CompletableFuture<Void>> submitSeatFutures = new ArrayList();
                for (UserInfo userInfo : USER_CONFIG.getList()) {
                    if (userInfo.getIsStart()){
                        submitSeatFutures.add(CompletableFuture.runAsync(new SubmitSeatFuture(userInfo,timeInterval, isAdmin,iSubmitSeatSuccessInfoService), threadPoolExecutor));
                    }
                }
                CompletableFuture.allOf(submitSeatFutures.toArray(new CompletableFuture[submitSeatFutures.size()])).join();
            } catch (Exception e) {
                log.error("执行抢座失败!", e);
            }
        }
        START.set(true);
    }


    public void emaillHandler(){
        /*List<UserInfo> list = USER_CONFIG.getList();
        String title=DateUtil.formatDate(new Date())+ " 抢座处理日报";
        ArrayList<StringBuilder> al = new ArrayList();
        list.stream().forEach(e ->{
            QueryWrapper<SubmitSeatSuccessInfo> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("phone", e.getPhone());
            queryWrapper.ge("create_time", DateUtil.beginOfDay(new Date()));
            List<SubmitSeatSuccessInfo> submitSeatSuccessInfos = iSubmitSeatSuccessInfoService.selectList(queryWrapper);
            if (CollUtil.isNotEmpty(submitSeatSuccessInfos)){
                StringBuilder stringBuilder = new StringBuilder(e.getName()+",今日进行了" + submitSeatSuccessInfos.size() + "次抢座处理。");
                List<SubmitSeatSuccessInfo> collect = submitSeatSuccessInfos.stream().filter(f -> f.getSuccess() > 0).collect(Collectors.toList());
                if (CollUtil.isNotEmpty(collect)){
                    Map<Integer, String> infoMap = collect.stream().collect(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(""))).stream().collect(Collectors.toMap(SubmitSeatSuccessInfo::getSeatNum, SubmitSeatSuccessInfo::getTime, (o, n) -> o + "," + n));
                    stringBuilder.append("成功抢到:[");
                    infoMap.forEach((k,v) ->{
                        stringBuilder.append("座位号:").append(k).append(",时间段:").append(v);
                    });
                    stringBuilder.append("]");
                }else {
                    stringBuilder.append("未能成功抢到预设座位!");
                }
                al.add(stringBuilder);
                if (StrUtil.isNotBlank(e.getEmail())){
                    iMailService.sendSimpleMail(e.getEmail(),title ,stringBuilder.toString());
                }
            }
        });
        for (StringBuilder stringBuilder : al) {
            log.info("{}",stringBuilder.toString());
        }
        iMailService.sendSimpleMail("1738870995@qq.com", title, JSONObject.toJSONString(al));*/
    }

}


